package com.ludomancy.selbst;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.geom.Arc2D;
import java.util.Vector;

import com.ludomancy.gamelib.Widget;

public class LifeWidget extends Widget
{
	private final int ENERGY_RADIUS = 64;
	private final double MAX_BEAM_WIDTH = 8; // the max size for the beam line
	private long lastSpawnTime;
	private Vector opportunities = new Vector();
	private final double POWER = 5; // the amount of available energy
	//private double powerFraction = 0.001; // power to give each time an op is clicked
	
	public LifeWidget(Widget parent, Rectangle area)
	{
		super(parent, area);
		lastSpawnTime = System.currentTimeMillis();
	}
	
	public void update()
	{
		if(System.currentTimeMillis() - lastSpawnTime > 5000)
		{
			spawnOpportunity();
		}
		for (int i = 0; i < opportunities.size();)
		{
			Opportunity op = (Opportunity) opportunities.elementAt(i);
			op.run();
			if(op.isGone())
			{
				opportunities.removeElementAt(i);
			}
			else
			{
				i++;
			}
		}
	}
	
	private void spawnOpportunity()
	{
		// make up a location for it
		double angle = Math.random() * Math.PI * 2;
		opportunities.add(new Opportunity(angle, 150));
		lastSpawnTime = System.currentTimeMillis();
	}
	
	public void paint(Graphics g)
	{
		Graphics2D g2 = (Graphics2D) g;
				
		g2.setColor(new Color(0x17ABB2));
		g2.fillRect(0, 0, getWidth(), getHeight());
		
		// paint beams
		g2.setColor(Color.YELLOW);
		Stroke old = g2.getStroke();
		Vector powered = getPoweredOpportunities();
		for (int i = 0; i < powered.size(); i++)
		{
			Opportunity current = (Opportunity) powered.elementAt(i);
			if(current.getPowerFeed() > 0)
			{
				double beamWidth = (current.getPowerFeed() * MAX_BEAM_WIDTH)/POWER;
				beamWidth = Math.max(0.1, beamWidth);
				BasicStroke stroke = new BasicStroke((float)beamWidth, BasicStroke.JOIN_MITER, BasicStroke.CAP_BUTT );
				g2.setStroke(stroke);
				g2.drawLine(getWidth()/2, getHeight()/2, current.getLocalPosition().x + getWidth()/2, current.getLocalPosition().y + getHeight()/2);
			}
		}
		g2.setStroke(old);
		
		// paint the energy source
		int energyX = (getWidth() - ENERGY_RADIUS)/2; 
		int energyY = (getHeight() - ENERGY_RADIUS)/2; 
		g2.setColor(new Color(0xFCDF00));
		Arc2D.Double energyEllipse = new Arc2D.Double(energyX, energyY, ENERGY_RADIUS, ENERGY_RADIUS, 0, 360, Arc2D.PIE);
		g2.fill(energyEllipse);
				
		// paint opportunities
		g2.translate(getWidth()/2, getHeight()/2);
		for (int i = 0; i < opportunities.size(); i++)
		{
			Opportunity op = (Opportunity) opportunities.elementAt(i);
			op.paint(g2);
		}
		g2.translate( -getWidth()/2, -getHeight()/2);
	}
	
	public void mouseDown(Point pos)
	{
		super.mouseDown(pos);
		// check if one of the opportunities was clicked
		for (int i = 0; i < opportunities.size(); i++)
		{
			Opportunity op = (Opportunity) opportunities.elementAt(i);
			if(op.isWithin(new Point(pos.x -getWidth()/2, pos.y -getHeight()/2)))
			{
				powerOpportunity(op);
				break;
			}
		}		
	}
	
	private Vector getPoweredOpportunities()
	{
		Vector powered = new Vector();
		for (int i = 0; i < opportunities.size(); i++)
		{
			Opportunity op = (Opportunity) opportunities.elementAt(i);
			if(op.getPowerFeed() > 0)
			{
				powered.add(op);
			}
		}
		return powered;
	}
	
	private double getTotalPowerFeed()
	{
		Vector powered = getPoweredOpportunities();
		double energy = 0;
		for (int i = 0; i < powered.size(); i++)
		{
			Opportunity current = (Opportunity) powered.elementAt(i);
			energy += current.getPowerFeed();
		}
		return energy;
	}

	private void powerOpportunity(Opportunity op)
	{
		Vector powered = getPoweredOpportunities();
		
		double powerFraction = 1.0 / (powered.size()+1);
		//double powerFraction = 1;
		double totalFeed = 0;
		for (int i = 0; i < powered.size(); i++)
		{
			Opportunity current = (Opportunity) powered.elementAt(i);
			if(current != op)
			{
				current.setPowerFeed(powerFraction*POWER);
//				current.removePowerFeed(powerFraction);
				totalFeed += current.getPowerFeed();
//				System.out.println("oppower: "+current.getPowerFeed());
			}
		}
		op.setPowerFeed(POWER - totalFeed);
		System.out.println("power: "+getTotalPowerFeed());
	}
}
